/**
 * @file   Driver.java
 * @author Enrique Madrid <e.madrid@lpcsite.com>
 * @date   Tue Oct  2 13:11:54 2007
 * 
 * @brief  
 * 
 * 
 */

package com.myt.matp.core;

import com.myt.matp.MATlet;
import com.myt.matp.utils.Queue;
import com.myt.matp.gui.GUI;

import java.util.*;

/**
 * 
 * 
 */
public final class Driver extends Ufo {

    // Message queue size
    private static final int QUEUE_INIT_SIZE = 16;

    public static final int MSG_EVENT = MSG_USER + 1;

    private Queue m_Pending = new Queue(QUEUE_INIT_SIZE);
    private Queue m_Recycle = new Queue(QUEUE_INIT_SIZE);

    
    public Driver(MATlet m) {
	super(m);
    }

    protected void run(final Msg msg) {
	Event e;

        //#ifdef DEBUG_DRIVER
        //# System.out.println(getClass().getName() + ".run(Msg) {");
        //#endif

	switch (msg.getId()) {
	case MSG_EVENT:
	    e = (Event)msg.getObject();
	    dispatchEvent(e);
	    m_Recycle.put(e);
	    break;
	}

        //#ifdef DEBUG_DRIVER
        //# System.out.println("}");
        //#endif
    }

    private Event createEvent(int id, int wParam, long dwParam, Object obj) {
	Event e = (Event)m_Recycle.get();
	if (e == null) {
	    e = new Event(id);
	}
	e.set(null);
	e.setId(id);
	e.setWParam(wParam);
	e.setDWParam(dwParam);
	e.setObject(obj);
	return e;
    }

    public boolean sendEvent(final Event e) {
	return dispatchEvent(e);
    }

    public boolean sendEvent(int id, int wParam, long dwParam, Object obj) {
	boolean ret;
	Event e = createEvent(id, wParam, dwParam, obj);
	ret = sendEvent(e);
	m_Recycle.put(e);
	return ret;
    }

    public void postEvent(final Event e) {
	Msg m = createMessage(this.MSG_EVENT);
	m.setObject(e);
	postMessage(m);
    }

    public void postEvent(int id, int iParam, long lParam, Object obj) {
	Event e = createEvent(id, iParam, lParam, obj);
	postEvent(e);
    }

    private boolean dispatchEvent(final Event e) {
        //#ifdef DEBUG_DRIVER
        //# System.out.println(getClass().getName() + ".dispatchEvent(Event) {");
        //#endif

        //#ifdef DEBUG_DRIVER
        //# System.out.println("\te.getId() = " + e.getId());
        //# System.out.println("\te.getWParam() = " + e.getWParam());
        //# System.out.println("\te.getDWParam() = " + e.getDWParam());
        //#endif

	boolean ret = true;
	if (!dispatchEventMATlet(e)) {
	    if (!dispatchEventModule(e)) {
		ret = dispatchEventGui(e);
	    }
	}

        //#ifdef DEBUG_DRIVER
        //# System.out.println("}");
        //#endif
	return ret;
    }

    private boolean dispatchEventMATlet(final Event e) {
	return m_MATlet.dispatchEvent(e);
    }

    private boolean dispatchEventModule(final Event e) {
	boolean ret = false;
	Module m = m_MATlet.getCurrentModule();
	if (m != null) {
	    ret = m.dispatchEvent(e);
	}
	return ret;
    }

    private boolean dispatchEventGui(final Event e) {
	boolean ret = false;
	GUI gui = m_MATlet.getGui();
	if (gui != null) {
	    ret = gui.dispatchEvent(e);
	}
	return ret;
    }

}
